﻿namespace Away.EventBusCore.Commands;

public abstract class Command<TResult> : ICommand<TResult>
{
    [JsonIgnore]
    public abstract string EventId { get; }

    /// <summary>
    /// 事件追溯编号：用于等待返回结果
    /// </summary>
    public string? TraceId { get; set; }

    /// <summary>
    /// 等待结果超时时间/毫秒
    /// </summary>
    [JsonIgnore]
    public int Timeout { get; set; } = 500;
}

public abstract class CommandHandler<TEvent, TResult> : IRequestHandler<TEvent, TResult> where TEvent : Command<TResult>
{
    private readonly IServiceScope _scope;
    public CommandHandler(IServiceProvider serviceProvider)
    {
        _scope = serviceProvider.CreateScope();
    }

    protected IServiceProvider ServiceProvider => _scope.ServiceProvider;
    protected ICommandSender Sender => ServiceProvider.GetRequiredService<ICommandSender>();


    public abstract Task<TResult> Handle(TEvent request);

    public async Task<TResult> Handle(TEvent request, CancellationToken cancellationToken)
    {
        var result = await Handle(request);
        await Sender.Send(request.TraceId!, result!);
        return result;
    }
}


public interface ICommand<out TResult> : IRequest<TResult>, ICmd { }

public interface ICommandHandler<in TEvent, TResult> : IRequestHandler<TEvent, TResult> where TEvent : ICommand<TResult> { }
